﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Centny
{
    public class SequencePanel : ExtScrollViewer, ISemanticZoomInformation
    {
        public interface ISequencable
        {
            String Sequence { get; }
        }
        public delegate IList<UIElement> OrderSequence(IList<UIElement> uis, ObservableCollection<String> sequences);
        private List<OrderSequence> _OrderSequences = new List<OrderSequence>();
        public event OrderSequence OnOrderSequence
        {
            add
            {
                this._OrderSequences.Add(value);
            }
            remove
            {
                this._OrderSequences.Remove(value);
            }
        }
        //public delegate void PanelLoaded(SequencePanel spanel, Panel panel);
        //private List<PanelLoaded> _PanelLoaded = new List<PanelLoaded>();
        //public event PanelLoaded OnPanelLoaded
        //{
        //    add
        //    {
        //        this._PanelLoaded.Add(value);
        //    }
        //    remove
        //    {
        //        this._PanelLoaded.Remove(value);
        //    }
        //}
        public SequencePanel()
        {
            this.Orientation = Orientation.Horizontal;
        }
        public Panel SPanel { get; set; }
        protected override void OnLoaded(object sender, RoutedEventArgs e)
        {
            base.OnLoaded(sender, e);
            this.SPanel = this.SViewer.Content as Panel;
            if (this.SPanel == null)
            {
                throw new InvalidCastException("the ScrollViewer Content is not a panel");
            }
            //switch (this.Orientation)
            //{
            //    case Orientation.Horizontal:
            //        this.SViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
            //        this.SViewer.HorizontalScrollMode = ScrollMode.Auto;
            //        this.SViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
            //        this.SViewer.VerticalScrollMode = ScrollMode.Disabled;
            //        break;
            //    case Orientation.Vertical:
            //        this.SViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
            //        this.SViewer.HorizontalScrollMode = ScrollMode.Disabled;
            //        this.SViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
            //        this.SViewer.VerticalScrollMode = ScrollMode.Auto;
            //        break;
            //}
            // this.Reload();
            //foreach (PanelLoaded pl in this._PanelLoaded)
            //{
            //    pl(this, this.SPanel);
            //}
        }
        /// <summary>
        /// the order sequences.
        /// </summary>
        public ObservableCollection<String> Sequences
        {
            get
            {
                ObservableCollection<String> _Sequences = new ObservableCollection<String>();
                foreach (UIElement ui in this.SPanel.Children)
                {
                    if (ui is ISequencable)
                    {
                        ISequencable seq = (ISequencable)ui;
                        _Sequences.Add(seq.Sequence);
                    }
                }
                return _Sequences;
            }
        }
        /// <summary>
        /// Get or Set the Orientation.
        /// </summary>
        public Orientation Orientation
        {
            get;
            set;
        }
        /// <summary>
        /// scroll to index of StackPanel children.
        /// </summary>
        /// <param name="idx">the children index of StackPanel</param>
        public void ScrollToIndex(int idx)
        {
            if (idx < 0 || idx >= this.SPanel.Children.Count)
            {
                return;
            }
            double offset = 0;
            for (int i = 0; i < idx; i++)
            {
                FrameworkElement ui = this.SPanel.Children[i] as FrameworkElement;
                switch (this.Orientation)
                {
                    case Orientation.Horizontal:
                        offset += ui.ActualWidth + ui.Margin.Left + ui.Margin.Right;
                        break;
                    case Orientation.Vertical:
                        offset += ui.ActualHeight + ui.Margin.Top + ui.Margin.Bottom;
                        break;
                }
            }
            switch (this.Orientation)
            {
                case Orientation.Horizontal:
                    this.ScrollAnimationHorOffset(offset);
                    break;
                case Orientation.Vertical:
                    this.ScrollAnimationVerOffset(offset);
                    break;
            }
        }
        public void ScrollToSequence(String seq)
        {
            double offset = 0;
            foreach (FrameworkElement ui in this.SPanel.Children)
            {
                if (ui is ISequencable)
                {
                    ISequencable s = (ISequencable)ui;
                    if (seq.Equals(s.Sequence))
                    {
                        break;
                    }
                }
                switch (this.Orientation)
                {
                    case Orientation.Horizontal:
                        offset += ui.ActualWidth + ui.Margin.Left + ui.Margin.Right;
                        break;
                    case Orientation.Vertical:
                        offset += ui.ActualHeight + ui.Margin.Top + ui.Margin.Bottom;
                        break;
                }
            }
            switch (this.Orientation)
            {
                case Orientation.Horizontal:
                    this.ScrollAnimationHorOffset(offset);
                    break;
                case Orientation.Vertical:
                    this.ScrollAnimationVerOffset(offset);
                    break;
            }
        }
        public void Reload()
        {
            IList<UIElement> ouis;
            if (this._OrderSequences.Count > 0)
            {
                ouis = this._OrderSequences[0](this.SPanel.Children, this.Sequences);
                foreach (UIElement ui in ouis)
                {
                    this.SPanel.Children.Remove(ui);
                    this.SPanel.Children.Insert(this.SPanel.Children.Count, ui);
                }
            }
            this.SPanel.UpdateLayout();
        }

        #region ISemanticZoomInformation
        // 摘要:
        //     获取或设置指示实现视图是否为活动视图的值。
        //
        // 返回结果:
        //     如果实现视图是活动视图，则为 true；否则为 false。
        public bool IsActiveView { get; set; }
        //
        // 摘要:
        //     获取或设置一个值，该值指示实现视图是否是语义更为完整的放大视图。
        //
        // 返回结果:
        //     如果实现视图是放大视图，则为 true；否则为 false。
        public bool IsZoomedInView { get; set; }
        //
        // 摘要:
        //     获取或设置承载实现视图的 SemanticZoom 所有者。
        //
        // 返回结果:
        //     承载此视图的 SemanticZoom。
        public SemanticZoom SemanticZoomOwner { get; set; }

        // 摘要:
        //     SemanticZoom 的整体视图更改时，将更改表示形式的相关方面（例如滚动 UI 或状态）。
        public void CompleteViewChange()
        {

        }
        //
        // 摘要:
        //     实现的视图是源视图，而新视图是可能不同的实现视图时，完成与视图更改相关的项操作。
        //
        // 参数:
        //   source:
        //     显示在源视图中的视图项。
        //
        //   destination:
        //     显示在目标视图中的视图项。
        public void CompleteViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination)
        {

        }
        //
        // 摘要:
        //     实现的视图是目标视图，而源视图是可能不同的实现视图时，完成与视图更改相关的项操作。
        //
        // 参数:
        //   source:
        //     显示在源视图中的视图项。
        //
        //   destination:
        //     显示在目标视图中的视图项。
        public async void CompleteViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination)
        {
        }
        //
        // 摘要:
        //     SemanticZoom 的整体视图将要更改时，初始化对表示的相关方面（例如滚动 UI 或状态）的更改。
        public void InitializeViewChange()
        {

        }
        //
        // 摘要:
        //     强制视图中的内容滚动，直到看到 SemanticZoomLocation 指定的项。如果找到，还聚焦该项。
        //
        // 参数:
        //   item:
        //     在视图中要滚动到的项。
        public void MakeVisible(SemanticZoomLocation item)
        {

        }
        //
        // 摘要:
        //     实现的视图是源视图，而挂起的目标视图是可能不同的实现视图时，初始化与视图更改相关的项操作。
        //
        // 参数:
        //   source:
        //     显示在源视图中的视图项。
        //
        //   destination:
        //     显示在目标视图中的视图项。
        public void StartViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination)
        {
        }
        //
        // 摘要:
        //     源视图是不同的视图，而挂起的目标视图是实现的视图时，初始化与视图更改相关的项操作。
        //
        // 参数:
        //   source:
        //     显示在源视图中的视图项。
        //
        //   destination:
        //     显示在目标视图中的视图项。
        public void StartViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination)
        {

        }
        #endregion
    }
    public class SeqGrid : Grid, SequencePanel.ISequencable
    {
        public String Sequence { get; set; }
    }
}
